package net.maergaiyun.service.impl;

import net.maergaiyun.controller.request.*;
import net.maergaiyun.enums.DateTimeFieldEnum;
import net.maergaiyun.enums.DeviceTypeEnum;
import net.maergaiyun.interceptor.LoginInterceptor;
import net.maergaiyun.mapper.VisitStatsMapper;
import net.maergaiyun.model.VisitStatsDO;
import net.maergaiyun.service.VisitStatsService;
import net.maergaiyun.vo.VisitStatsVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class VisitStatsServiceImpl implements VisitStatsService {
    @Autowired
    private VisitStatsMapper visitStatsMapper;

    @Override
    public Map<String, Object> pageVisitRecord(VisitRecordPageRequest request) {

        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();

        Map<String, Object> data = new HashMap<>();
        String code = request.getCode();
        int page = request.getPage();
        int size = request.getSize();

        int count = visitStatsMapper.countTotal(code, accountNo);
        int from = (page - 1) * size;

        List<VisitStatsDO> list = visitStatsMapper.pageVisitRecord(code, accountNo, from, size);
        List<VisitStatsVO> visitStatsVOList = list.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());
        data.put("total", count);
        data.put("current_page", page);

        // 计算总页数
        int totalPage = 0;
        if (count % size == 0) {
            totalPage = count / size;
        } else {
            totalPage = count / size + 1;
        }
        data.put("total_page", totalPage);

        data.put("data", visitStatsVOList);

        return data;
    }

    @Override
    public List<VisitStatsVO> queryRegionWithDay(RegionQueryRequest request) {
        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();

        String code = request.getCode();
        String startTime = request.getStartTime();
        String endTime = request.getEndTime();

        List<VisitStatsDO> visitStatsDOList = visitStatsMapper.queryRegionVisitStatsWithDay(code, accountNo, startTime, endTime);
        List<VisitStatsVO> visitStatsVOList = visitStatsDOList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());
        return visitStatsVOList;
    }

    @Override
    public List<VisitStatsVO> queryVisitTrend(VisitTrendQueryRequest request) {
        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();
        String code = request.getCode();

        String type = request.getType();
        String startTime = request.getStartTime();
        String endTime = request.getEndTime();
        List<VisitStatsDO> visitStatsDOList = null;
        if (DateTimeFieldEnum.DAY.name().equalsIgnoreCase(type)) {
            visitStatsDOList = visitStatsMapper.queryVisitTrendWithDay(code, accountNo, startTime, endTime);
        } else if (DateTimeFieldEnum.HOUR.name().equalsIgnoreCase(type)) {
            visitStatsDOList = visitStatsMapper.queryVisitTrendWithHour(code, accountNo, startTime);
        } else if (DateTimeFieldEnum.MINUTE.name().equalsIgnoreCase(type)) {
            visitStatsDOList = visitStatsMapper.queryVisitTrendWithMinute(code, accountNo, startTime, endTime);
        }

        if (visitStatsDOList != null) {
            List<VisitStatsVO> visitStatsVOList = visitStatsDOList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());
            return visitStatsVOList;
        } else {
            return null;
        }
    }

    @Override
    public List<VisitStatsVO> queryFrequentSource(FrequentSourceRequest request) {
        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();
        String code = request.getCode();

        String startTime = request.getStartTime();
        String endTime = request.getEndTime();

        List<VisitStatsDO> visitStatsDOList = visitStatsMapper.queryFrequentSource(code, accountNo, startTime, endTime, 10);
        List<VisitStatsVO> visitStatsVOList = visitStatsDOList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());

        return visitStatsVOList;
    }

    @Override
    public Map<String, Object> queryDeviceInfo(DeviceQueryRequest request) {
        Long accountNo = LoginInterceptor.threadLocal.get().getAccountNo();
        String code = request.getCode();

        String startTime = request.getStartTime();
        String endTime = request.getEndTime();

        String os = DeviceTypeEnum.OS.name().toLowerCase();
        String browser = DeviceTypeEnum.BROWSER.name().toLowerCase();
        String device = DeviceTypeEnum.DEVICE.name().toLowerCase();

        List<VisitStatsDO> osList = visitStatsMapper.queryDeviceInfo(code, accountNo, startTime, endTime, os);
        List<VisitStatsDO> browserList = visitStatsMapper.queryDeviceInfo(code, accountNo, startTime, endTime, browser);
        List<VisitStatsDO> deviceList = visitStatsMapper.queryDeviceInfo(code, accountNo, startTime, endTime, device);


        List<VisitStatsVO> osVisitStatsVOList = osList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());
        List<VisitStatsVO> browserVisitStatsVOList = browserList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());
        List<VisitStatsVO> deviceVisitStatsVOList = deviceList.stream().map(obj -> beanProcess(obj)).collect(Collectors.toList());

        Map<String, Object> map = new HashMap<>();
        map.put("os", osVisitStatsVOList);
        map.put("browser", browserVisitStatsVOList);
        map.put("device", deviceVisitStatsVOList);

        return map;
    }

    public VisitStatsVO beanProcess(VisitStatsDO visitStatsDO) {
        VisitStatsVO visitStatsVO = new VisitStatsVO();
        BeanUtils.copyProperties(visitStatsDO, visitStatsVO);
        return visitStatsVO;
    }
}
